package com.sky.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.sky.constant.MessageConstant;
import com.sky.constant.StatusConstant;
import com.sky.context.BaseContext;
import com.sky.dto.DishDTO;
import com.sky.dto.SetmealDTO;
import com.sky.entity.*;
import com.sky.exception.DeletionNotAllowedException;
import com.sky.exception.SetmealEnableFailedException;
import com.sky.exception.SetmealNameDuplicateException;
import com.sky.mapper.CategoryMapper;
import com.sky.result.PageResult;
import com.sky.service.CategoryService;
import com.sky.vo.DishVO;
import com.sky.vo.SetmealVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Service
public class CategoryServiceimpl implements CategoryService {
    @Autowired
    private CategoryMapper categoryMapper;

    @Override
    public void putMeal(SetmealDTO setmealDTO) {
        Setmeal setmeal = new Setmeal();
        BeanUtils.copyProperties(setmealDTO, setmeal);
        setmeal.setStatus(StatusConstant.DISABLE);
        categoryMapper.putMeal(setmeal);
        categoryMapper.deleteSetmealDish(setmealDTO.getId());
        List<SetmealDish> setmealDishes = setmealDTO.getSetmealDishes();
        for (SetmealDish setmealDish : setmealDishes) {
            setmealDish.setSetmealId(setmealDTO.getId());
        }
        categoryMapper.addSetmealDish(setmealDishes);
    }

    @Override
    public PageResult getMeals(Integer page, Integer pageSize, Long categoryId, String name, Integer status) {
        PageHelper.startPage(page, pageSize);
        Page<SetmealVO> pager = categoryMapper.getMeals(categoryId, name, status);
        PageResult pageResult = new PageResult(pager.getTotal(), pager.getResult());
        return pageResult;
    }

    @Override
    public void deleteMeal(List<Long> ids) {
        for (Long id : ids) {
            List<Long> dishIds = categoryMapper.getDishIdBySetMealId(id);
            for (Long dishId : dishIds) {
                DishVO dishVO = categoryMapper.getDishById(dishId);
                Integer status = dishVO.getStatus();
                if (status == StatusConstant.ENABLE) {
                    throw new DeletionNotAllowedException(MessageConstant.SETMEAL_ON_SALE);
                }
            }
        }
        categoryMapper.deleteMeals(ids);
    }

    @Override
    public void startOrStopMeal(Integer status, Long id) {
        if (status == StatusConstant.ENABLE) {
            //如果这是一个起售操作status会是1
            //就进去判断是否有菜品在售卖如果有就报错
            List<Long> disnIds = categoryMapper.getDishIdBySetMealId(id);
            //根据套餐id去查询然后返回一个所包含菜品的id集合，之后进行遍历，获取到菜品本体再获取到菜品的起售停止售状态
            for (Long disnId : disnIds) {
                Integer dishStatus = categoryMapper.getDishsById(disnId);
                if (dishStatus == StatusConstant.DISABLE) {
                    throw new SetmealEnableFailedException(MessageConstant.SETMEAL_ENABLE_FAILED);
                }
            }
        }
        Setmeal setmeal = new Setmeal();
        setmeal.setStatus(status);
        setmeal.setId(id);
        categoryMapper.putMeal(setmeal);
    }

    @Override
    public void addMeal(SetmealDTO setmealDTO) {
        Setmeal setmeal = new Setmeal();
        BeanUtils.copyProperties(setmealDTO, setmeal);
        String name = setmeal.getName();
        Setmeal setmealBySetmealName = categoryMapper.getSetmealBySetmealName(name);
        if (setmealBySetmealName != null) {
            throw new SetmealNameDuplicateException(MessageConstant.SETMEAL_EXITES);
        }
        categoryMapper.addSetmeal(setmeal);
        List<SetmealDish> setmealDishes = setmealDTO.getSetmealDishes();
        for (SetmealDish setmealDish : setmealDishes) {
            Long dishId = categoryMapper.getDishIdByName(setmealDish.getName());
            setmealDish.setDishId(dishId);
            setmealDish.setSetmealId(setmeal.getId());
        }
        categoryMapper.addSetmealDish(setmealDishes);
    }

    @Override
    public SetmealVO getMealByid(Long id) {
        Setmeal setmeal = categoryMapper.getMealByid(id);
        SetmealVO setmealVO = new SetmealVO();
        BeanUtils.copyProperties(setmeal, setmealVO);
        List<SetmealDish> dishBySetMealId = categoryMapper.getDishBySetMealId(id);
        setmealVO.setSetmealDishes(dishBySetMealId);
        return setmealVO;
    }

    @Override
    public void updateCategory(Category category) {
        category.setUpdateUser(BaseContext.getCurrentId());
        category.setUpdateTime(LocalDateTime.now());
        categoryMapper.updateCategory(category);
    }

    @Override
    public PageResult getCategorys(Integer page, Integer pageSize, String name, Integer type) {
        PageHelper.startPage(page, pageSize);
        Page<Category> pc = categoryMapper.getCategorys(name, type);
        PageResult pageResult = new PageResult(pc.getTotal(), pc.getResult());
        return pageResult;
    }

    @Override
    public void startOrStopCategory(Integer status, Long id) {
        Category category = new Category();
        category.setId(id);
        category.setStatus(status);
        categoryMapper.updateCategory(category);
    }

    @Override
    public void addCategory(Category category) {
        Long currentId = BaseContext.getCurrentId();
        LocalDateTime now = LocalDateTime.now();
        category.builder().createTime(now).createUser(currentId).updateTime(now).updateUser(currentId);
        categoryMapper.addCategory(category);
    }

    @Override
    public List<Category> getCategoryByType(Integer type) {
        List<Category> category = categoryMapper.getCategoryByType(type);
        return category;
    }

    @Override
    public List<DishVO> getDishByCategoryId(Long id) {
        List<DishVO> list = categoryMapper.getDishByCategoryId(id);
        for (DishVO dishVO : list) {
            List<DishFlavor> flavorsByDishId = categoryMapper.getFlavorsByDishId(dishVO.getId());
            dishVO.setFlavors(flavorsByDishId);
        }

        return list;
    }

    @Override
    public void deleteCategory(Long id) {
        categoryMapper.deleteCategory(id);
    }

    @Override
    public PageResult pageDish(Long categoryId, String name, Integer page, Integer pageSie, Integer status) {
        PageHelper.startPage(page, pageSie);
        Page<DishVO> pageDish = (Page<DishVO>) categoryMapper.pageDish(categoryId, name, status);
        PageResult pageResult = new PageResult(pageDish.getTotal(), pageDish.getResult());
        return pageResult;
    }

    @Override
    public DishVO getDishById(Long id) {
        DishVO dish = categoryMapper.getDishById(id);
        List<DishFlavor> flavors = categoryMapper.getFlavorsByDishId(id);
        if (flavors == null) {
            return dish;
        } else {
            dish.setFlavors(flavors);
            return dish;
        }
    }

    @Override
    public void updateDish(DishVO dish) {
        List<DishFlavor> flavors = dish.getFlavors();
        List<Long> longs = new ArrayList<>();
        longs.add(dish.getId());
        categoryMapper.deleteflavor(longs);
        for (DishFlavor flavor : flavors) {
            flavor.setDishId(dish.getId());
        }
        categoryMapper.addDishFlavor(flavors);

        Dish dish1 = new Dish();
        BeanUtils.copyProperties(dish, dish1);
        categoryMapper.updateDish(dish1);
    }

    @Override
    public Long addDish(DishDTO dishDTO) {
        Long currentId = BaseContext.getCurrentId();
        LocalDateTime now = LocalDateTime.now();
        Dish dish = new Dish();
        BeanUtils.copyProperties(dishDTO, dish);
        dish.builder().createUser(currentId).createTime(now).updateTime(now).updateUser(currentId).build();
        Long dishId = categoryMapper.addDish(dish);
        dishDTO.setId(dishId);
        List<DishFlavor> flavors = dishDTO.getFlavors();
        for (DishFlavor flavor : flavors) {
            flavor.setDishId(dish.getId());
        }
        categoryMapper.addDishFlavor(flavors);


        return dishId;
    }

    @Override
    public void startOrStop(Integer status, Long id) {
        Dish dish = new Dish();
        dish.setStatus(status);
        dish.setId(id);
        List<Long> setmealIdByDishIds = categoryMapper.getDishSetMealId(id);
        for (Long setmealIdByDishId : setmealIdByDishIds) {
            Integer statusBySermealId = categoryMapper.getSetmealStatusBySermealId(setmealIdByDishId);
            if (statusBySermealId == StatusConstant.ENABLE) {
                startOrStopMeal(StatusConstant.DISABLE, setmealIdByDishId);
            }
        }
        categoryMapper.updateDish(dish);
    }

    @Override
    public void deleteDish(List<Long> ids) {
        for (Long id : ids) {
            DishVO dishById = categoryMapper.getDishById(id);
            if (dishById.getStatus() == StatusConstant.ENABLE) {
                throw new DeletionNotAllowedException(MessageConstant.DISH_ON_SALE);
            }

            List<Long> setMealId = categoryMapper.getDishSetMealId(id);
            if (setMealId != null && setMealId.size() > 0) {
                throw new DeletionNotAllowedException(MessageConstant.DISH_BE_RELATED_BY_SETMEAL);
            }
            categoryMapper.deleteflavor(ids);
            categoryMapper.deleteDish(ids);
        }

    }

    @Override
    public List<Dish> getDishBycategoryId(Long categoryId) {
        List<Dish> dish = categoryMapper.getDishBycategoryId(categoryId);
        return dish;
    }

    @Override
    public List<Category> getTypeListByStatus(Integer type) {
        return categoryMapper.getTypeListByStatus(type);
    }

    @Override
    public List<SetmealVO> getsetmealByCategoryId(Long category) {
        List<SetmealVO> setmealVOS = categoryMapper.getsetmealByCategoryId(category);
        for (SetmealVO setmealVO : setmealVOS) {
           List<SetmealDish> setMealDishBysetMealId= categoryMapper.getSetMealDishBysetMealId(setmealVO.getId());
           setmealVO.setSetmealDishes(setMealDishBysetMealId);
        }

        return setmealVOS;
    }

    @Override
    public List<DishVO> getDishesBySetmealId(Long setmealId) {
        List<Long> dishIdBySetMealId = categoryMapper.getDishIdBySetMealId(setmealId);
        List<DishVO> dishes = new ArrayList<>();
        for (Long l : dishIdBySetMealId) {
            DishVO dishVO = categoryMapper.getDishById(l);
            List<DishFlavor> flavorsByDishId = categoryMapper.getFlavorsByDishId(l);
            dishVO.setFlavors(flavorsByDishId);
            dishes.add(dishVO);
        }
        return dishes;
    }
}
